# app/services/family/family.py
from typing import List, Dict, Any, Optional
from tortoise.transactions import atomic
from tortoise.expressions import Q

from app.services.base.base_service import BaseService
from app.models import Family, FamilyMember, User
from app.schemas.family.family_system import FamilyCreate, FamilyUpdate
from app.core.exceptions import BusinessError
from app.utils.app_log import logger
from app.schemas.base.error_code import *

class FamilyService(BaseService):
    """家庭服务类"""
    def __init__(self):
        super().__init__(model=Family, resource_name="家庭")

    async def get_family_members(self, family_id: int) -> List[FamilyMember]:
        """获取家庭的所有成员"""
        try:
            await self.get_safe(family_id)
            return await FamilyMember.filter(family_id=family_id, is_active=True).select_related('user')

        except Exception as e:
            # logger.error(f"获取家庭成员失败: {str(e)}")
            raise BusinessError(RESOURCE_NOT_FOUND.format(resource = "家庭成员"),
                                details = f"{family_id}获取家庭成员失败: {str(e)}")
        
    async def get_family_tree(self, name: Optional[str] = None) -> List[Dict[str, Any]]:
        """获取家庭树结构（包含成员信息）"""
        try:
            q = Q(is_deleted=False)
            if name:
                q &= Q(name__contains=name)
            all_families = await self.model.filter(q).order_by("order")

            async def get_family_members(family_id: int):
                """获取家庭成员信息"""
                logger.info(f"获取家庭成员 {family_id}")
                reuslt = []
                members = await FamilyMember.filter(
                    family_id=family_id, 
                    # is_active=True
                ).select_related('user').all()
                for member in members:
                    reuslt.append({
                        "id": member.id,
                        "user_id": member.user_id,
                        "nickname": member.nickname,
                        "avatar": member.avatar,
                        "is_admin": member.is_admin,
                        "is_active": member.is_active,
                        "joined_at": str(member.joined_at) if member.joined_at else None,
                        "username": getattr(member.user, 'username', None) if hasattr(member, 'user') else None,
                        "email": getattr(member.user, 'email', None) if hasattr(member, 'user') else None,
                    })
                # logger.info(f"获取家庭成员结果 {family_id} {reuslt}")
                return reuslt
    
            async def build_tree(parent_id):
                result = []
                for family in all_families:
                    if family.parent_id == parent_id:
                        members = await get_family_members(family.id)
                        children = await build_tree(family.id)
                        result.append({
                            "id": family.id,
                            "name": family.name,
                            "description": family.description,
                            "order": family.order,
                            "parent_id": family.parent_id,
                            "avatar": family.avatar,
                            "max_members": family.max_members,
                            "created_by": family.created_by_id,
                            "created_at": str(family.created_at) if family.created_at else None,
                            "updated_at": str(family.updated_at) if family.updated_at else None,
                            "is_active": family.is_active,
                            "member_count": len(members),
                            "members": members,
                            "children": children,
                        })
                # logger.info(f"结果 {result}")
                return result
            
            return await build_tree(0)
            
        except Exception as e:
            raise BusinessError(
                RESOURCE_NOT_FOUND.format(resource="家庭树"),
                details=f"获取家庭树失败: {str(e)}"
            )

    async def get_family_info(self, family_id: int) -> Dict[str, Any]:
        """获取家庭详细信息"""
        try:
            family = await self.get_safe(family_id)
            members = await FamilyMember.filter(family_id=family_id, is_active=True).select_related('user')
            
            member_list = []
            for member in members:
                member_list.append({
                    "id": member.id,
                    "user_id": member.user_id,
                    "nickname": member.nickname,
                    "avatar": member.avatar,
                    "is_admin": member.is_admin,
                    "joined_at": member.joined_at,
                    "permissions": member.permissions
                })
            
            return {
                "family": family,
                "members": member_list,
                "member_count": len(member_list)
            }
        except Exception as e:
            # logger.error(f"获取家庭详情失败: {str(e)}")
            raise BusinessError(RESOURCE_NOT_FOUND.format(resource = "家庭详情"),
                                    details=f"""获取家庭详情失败: {str(e)}""")

    @atomic()
    async def create_family(self, obj_in: FamilyCreate, creator_id: int) -> Family:
        """创建家庭"""
        try:
            # 检查父家庭是否存在
            if obj_in.parent_id != 0:
                await self.get_safe(obj_in.parent_id)

            creator_id = await self._get_current_user_id()
            # 检查用户是否存在
            user = await User.get_or_none(id=creator_id)
            if not user:
                raise BusinessError(RESOURCE_NOT_FOUND.format(resource = "用户"),
                                    details=f"""创建者用户{creator_id}不存在: {str(e)}""")
            
            # 创建家庭
            obj_in_dict = obj_in.model_dump(exclude_unset=True)
            obj_in_dict['created_by_id'] = creator_id
            new_family = await self.validate_and_create(obj_in_dict)
            
            # 创建创建者的家庭成员关系（作为管理员）
            family_member = FamilyMember(
                user_id=creator_id,
                family_id=new_family.id,
                nickname=obj_in.name,
                is_admin=True,
                is_active=True
            )
            await family_member.save()
            
            logger.info(f"用户 {creator_id} 创建家庭 {new_family.id}")
            return new_family
  
        except Exception as e:
            # logger.error(f"创建家庭失败: {str(e)}")
            raise BusinessError(RESOURCE_CREATE_FAILED.format(resource = "家庭"),
                                    details=f"""创建家庭失败: {str(e)}""")

    @atomic()
    async def update_family(self, obj_in: FamilyUpdate) -> Family:
        """更新家庭信息"""
        try:
            family_obj = await self.get_safe(obj_in.id)
            
            update_data = obj_in.model_dump(exclude_unset=True)
            if 'id' in update_data:
                del update_data['id']
                
            updated_family = await self.validate_and_update(obj_in.id, update_data)
            
            logger.info(f"更新家庭 {obj_in.id}")
            return updated_family
        except BusinessError:
            raise
        except Exception as e:
            # logger.error(f"更新家庭失败: {str(e)}")
            raise BusinessError(RESOURCE_UPDATE_FAILED.format(resource = "家庭"),
                                    details=f"""更新家庭失败: {str(e)}""")

    @atomic()
    async def delete_family(self, family_id: int) -> Family:
        """删除家庭（软删除）"""
        try:
            family_obj = await self.get_safe(family_id)
            family_obj.is_deleted = True
            await family_obj.save()
            
            # 软删除所有家庭成员关系
            await FamilyMember.filter(family_id=family_id).update(is_active=False)
            
            logger.info(f"删除家庭 {family_id}")
            return family_obj
        except BusinessError:
            raise
        except Exception as e:
            # logger.error(f"删除家庭失败: {str(e)}")
            raise BusinessError(RESOURCE_DELETE_FAILED.format(resource = "家庭"),
                                    details=f"""删除家庭失败: {str(e)}""")

    async def _delete_children_recursive(self, parent_id: int):
        """递归删除子家庭"""
        try:
            children = await Family.filter(parent_id=parent_id, is_deleted=False)
            for child in children:
                child.is_deleted = True
                await child.save()
                await FamilyMember.filter(family_id=child.id).update(is_active=False)
                await self._delete_children_recursive(child.id)
        except Exception as e:
            # logger.error(f"递归删除子家庭失败: {str(e)}")
            raise BusinessError(RESOURCE_DELETE_FAILED.format(resource = "子家庭"),
                                    details=f"""递归删除子家庭失败: {str(e)}""")

    @atomic()
    async def add_family_member(self, family_id: int, user_id: int, nickname: str = None, is_admin: bool = False) -> FamilyMember:
        """添加家庭成员"""
        try:
            # 检查家庭是否存在且未删除
            family = await self.get_safe(family_id)
            
            # 检查用户是否存在
            user = await User.get_or_none(id=user_id)
            if not user:
                raise BusinessError(RESOURCE_NOT_FOUND.format(resource = "用户"),
                                    details=f"""用户{user_id}不存在家庭: {str(e)}""")
                
            # 检查是否已满员
            if await family.is_full():
                raise BusinessError(VALIDATION_ERROR,details=f"""家庭{family_id}已满员""" )
                
            # 检查成员是否已存在
            existing_member = await FamilyMember.get_or_none(family_id=family_id, user_id=user_id)
            if existing_member and existing_member.is_active:
                raise BusinessError(RESOURCE_ALREADY_EXISTS.format(resource = "用户"),
                                details = f"""用户{user_id}已存在家庭{family_id}: {str(e)}""")
                
            # 创建或更新成员关系
            if existing_member:
                existing_member.is_active = True
                existing_member.nickname = nickname or existing_member.nickname
                existing_member.is_admin = is_admin
                await existing_member.save()
                result_member = existing_member
            else:
                family_member = FamilyMember(
                    user_id=user_id,
                    family_id=family_id,
                    nickname=nickname or user.username,
                    is_admin=is_admin,
                    is_active=True
                )
                await family_member.save()
                result_member = family_member
            
            logger.info(f"添加用户 {user_id} 到家庭 {family_id}")
            return result_member

        except Exception as e:
            # logger.error(f"添加家庭成员失败: {str(e)}")
            raise BusinessError(RESOURCE_CREATE_FAILED.format(resource = "用户"),
                                details = f"""添加{user_id}家庭{family_id}成员失败: {str(e)}""")

    @atomic()
    async def remove_family_member(self, family_id: int, user_id: int) -> FamilyMember:
        """移除家庭成员"""
        try:
            member = await FamilyMember.get_or_none(family_id=family_id, user_id=user_id, is_active=True)
            if not member:
                raise BusinessError(RESOURCE_NOT_FOUND.format(resource = "用户"),
                                details = f"""{user_id}不是{family_id}家庭成员: {str(e)}""")
                
            # 不能移除最后一个管理员
            admin_count = await FamilyMember.filter(family_id=family_id, is_admin=True, is_active=True).count()
            if member.is_admin and admin_count <= 1:
                raise BusinessError(RESOURCE_DELETE_FAILED.format(resource = "家庭管理员"),
                                details = f"""移除家庭管理员 {user_id}失败: {str(e)}""")
                
            member.is_active = False
            await member.save()
            
            logger.info(f"从家庭 {family_id} 移除用户 {user_id}")
            return member
  
        except Exception as e:
            # logger.error(f"移除家庭成员失败: {str(e)}")
            raise BusinessError(RESOURCE_DELETE_FAILED.format(resource = "用户"),
                                details = f"""移除家庭成员 {user_id}失败: {str(e)}""")

    async def get_user_families(self, user_id: int) -> List[Family]:
        """获取用户所属的所有家庭"""
        try:
            # 检查用户是否存在
            user = await User.get_or_none(id=user_id)
            if not user:
                raise BusinessError(RESOURCE_NOT_FOUND.format(resource = "用户"),
                                details = f"""用户 {user_id}不存在: {str(e)}""")
                
            family_members = await FamilyMember.filter(user_id=user_id, is_active=True).select_related('family')
            return [fm.family for fm in family_members if not fm.family.is_deleted]

        except Exception as e:
            # logger.error(f"获取用户家庭失败: {str(e)}")
            raise BusinessError(RESOURCE_NOT_FOUND.format(resource = "家庭"),
                                details = f"""{user_id}获取用户家庭成员: {str(e)}""")




# 全局实例
family_service = FamilyService()